package com.aop.log.aspect;

import com.aop.log.entity.MyLog;
import com.aop.log.service.MyLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 * @date 2020/10/30 15:42
 */
@Aspect
@Component
@Slf4j
public class OpenLogAspectJ {


    @Autowired
    private MyLogService service;

    @Autowired
    private HttpServletRequest request;

//    访问时间
    private Date date;

//    访问的类
    private Class aClass;

//    访问的方法
    private Method method;


    /**
     * 设置切入点为全部的controller
     */
    @Pointcut("execution(* com.aop.log.controller.*.*(..))")
    public void myLogPointcut(){
    }


    @Before(value = "myLogPointcut()")
    public void saveOpenLog(JoinPoint joinPoint) throws NoSuchMethodException {
        System.out.println("前置拦截");
//        赋值当前时间
        date = new Date();

//        访问的类名称
        aClass = joinPoint.getTarget().getClass();

//        访问的方法名称
        String methodName = joinPoint.getSignature().getName();

        Object[] args = joinPoint.getArgs();
        if (ObjectUtils.isEmpty(args)){
//            获取无参方法
            method = aClass.getMethod(methodName);
        }else {
            Class[] classes = new Class[args.length];
            for (int i = 0; i < args.length; i++) {
                classes[i] = args[i].getClass();
            }
            method = aClass.getMethod(methodName,classes);
        }
    }

    @After(value = "myLogPointcut()")
    public void doAfter(){
        System.out.println("后置拦截");

        // 获取访问的IP
        String ip = request.getRemoteAddr();

        // 获取访问的url
        if (ObjectUtils.isEmpty(aClass) || ObjectUtils.isEmpty(method) || Objects.equals(aClass, MyLog.class)) {
            log.error("【路径异常】");
            return;
        }
        // 获取携带 @RequestMapping注解的类
        Annotation annotation = aClass.getAnnotation(RequestMapping.class);
        RequestMapping requestMapping = null;

        if (annotation instanceof RequestMapping) {
            requestMapping = (RequestMapping) annotation;
        }

        if (ObjectUtils.isEmpty(requestMapping)) {
            log.error("【对象异常】");
            return;
        }

        String[] classUrl = requestMapping.value();
        RequestMapping methodAnnotation = method.getAnnotation(RequestMapping.class);
        if (ObjectUtils.isEmpty(methodAnnotation)) {
            log.error("【方法异常】");
            return;
        }
        String[] methodUrl = methodAnnotation.value();
        String url = classUrl[0] + "/" + methodUrl[0];

//        登录之后去session中获取访问者id..
        HttpSession session = request.getSession();

        MyLog myLog = new MyLog();
//        访问者id
        myLog.setUserLog(1);
        myLog.setLogIp(ip);
        myLog.setLogUrl(url);
        myLog.setLogMethod("[类名]：" + aClass.getName() + "[方法名] ：" + method.getName());
        myLog.setCreateTime(date);
        service.saveLog(myLog);

    }


}
